package com.fingard.dsp.bank.directbank.chinapay05;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RefundState;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.util.ZipHelper;

/**
 * 中国银联对账单获取 支持交易：快捷支付、网关支付
 *
 * @author Xuejy
 * @date 2019年01月17日
 */
public class ChinaPay05Statement extends ChinaPay05Base implements IStatement {
    public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
        RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
        retAts.writeStart();

        String[] gatewayRespHeader = null;
        String requestType = getBankConfig().getValueAsString("requestType");
        if ("sftp".equalsIgnoreCase(requestType)) {
        	gatewayRespHeader = getGatewayStatementBySFTP(p_reqQrySttm, retAts);
        } else {
        	gatewayRespHeader = getGatewayStatementByHttps(p_reqQrySttm, retAts);
        }
        String gatewayTotalNum = retAts.totalNum;

        if ("-1".equals(gatewayRespHeader[0])) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo("网关支付对账单获取失败原因:" + gatewayRespHeader[1]);
        } else {
            if (retAts.getWrittenRdCount() == 0) {
                retAts.writeRespCode("0");
                retAts.writeRespInfo("本日无交易记录!");
            }
            retAts.isWritedTotalNum(gatewayTotalNum);
        }

        retAts.writeEnd();
        return retAts;
    }
    
    /**
     * 网关支付对账单下载
     *
     * @param p_reqQrySttm
     * @param retAts
     * @return
     * @throws Exception
     */
    public String[] getGatewayStatementByHttps(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
        String[] tmpRespHeader = new String[]{"", ""};
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.totalNum = "0";
        int totalNum = 0;
        
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "gateway");
            if (actItem != null) {
                // FTP服务器配置信息
                String localPath = getBankConfig().getValueAsString("statementFileFath");
                String merchantId = actItem.merchantId;
                if (merchantId != null&& !"".equals(merchantId)) {
                    if (!"".equals(localPath)) {
                        localPath = StringHelper.trimEnd(localPath, File.separator) + File.separator;
                        // 从本地文件读取对账单数据
                        //文件名格式：商户号_商户交易日期_生成文件时间戳（yyyyMMddHHmmss）_x_y.zip
                        //商户号:长度 15 位
                        //商户交易日期:8 位
                        //时间戳:yyyyMMddHHmmss
                        String filePath =localPath + Format.Date8Format.format(p_reqQrySttm.getBusDate());
                        String[] files = FileHelper.listFiles(filePath);
                        WriteBankLogLn("从" + filePath + "读取对账单文件");
                        if (files != null) {
                            List<String> list = Arrays.asList(files);
                            for (String file : files) {
                                String dirName = file.substring(0, file.lastIndexOf("."))+".txt";
                                if (!file.startsWith(merchantId) ||(file.endsWith(".zip")&&list.contains(dirName))) {
                                    continue;
                                }
                                if (file.endsWith(".zip")) {
                                    WriteBankLogLn("开始解压文件" + file);
                                    ZipHelper.unzipFile(filePath + File.separator + file, filePath, true);
                                    //解压后的文件夹
                                    file = dirName;
                                }
                                String content = FileHelper.readFileText(filePath + File.separator + file, getCharset());
                                if (content == null || "".equals(content)) {
                                    WriteBankLogLn(file + "文件内容有误");
                                    continue;
                                }
                                WriteBankLogLn("对账单文件内容:\r\n" + content);
                                String spliter = "\n";
                                if (content.contains("\r\n")) {
                                    spliter = "\r\n";
                                }

                                String[] line = content.split(spliter);
//                                    String sign = line[line.length - 1]; //签名原字段
                                StringBuilder plain = new StringBuilder();
                                plain.append(line[0]);
                                tmpRespCode = "0";
                                String[] lines = line[0].split("\\|", -1);
                                if (lines.length >= 15) {
                                    totalNum = totalNum + Integer.parseInt(lines[1].trim());
                                } else {
                                    WriteBankLogLn("对账单文件格式有误,请检查");
                                    continue;
                                }
                                for (int x = 1; x < line.length-1;x++) {
                                    plain.append(line[x]);
                                    lines = line[x].split("\\|", -1);
                                    if (lines.length >= 30) {
                                        String orderState = lines[10].trim();
                                        RetAtsStatementDetail retDetail = new RetAtsStatementDetail();
                                        retDetail.busTime = lines[0].trim()+lines[17].trim();
                                        retDetail.busType = lines[8].trim();
                                        retDetail.bkSeq = lines[5].trim();
                                        retDetail.askNumber = lines[5].trim();
                                        retDetail.cur = convertCurToATS(lines[7].trim());
                                         //0401退票
                                        if ("0401".equals(retDetail.busType)) {
                                            retDetail.refundAmt = StringHelper.amountDivide100(lines[14].trim());
                                            //1027退款调账成功  0000成功
                                            if ("1027".equals(orderState)) {
                                                retDetail.refundState = RefundState.RefundSuccess;
                                            } else {
                                                retDetail.refundState = RefundState.RefundFail;
                                            }
                                        } else {
                                            retDetail.amount = StringHelper.amountDivide100(lines[14].trim());
                                            if ("0000".equals(orderState)) {
                                                retDetail.transState = TransState.Success;
                                            } else {
                                                retDetail.transState = TransState.Fail;
                                            }
                                        }
                                        retAts.writeRetDetail(retDetail);
                                    }
                                }

                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = filePath + "路径下不存在对账单文件。";
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = "未配置本地对账存放路径";
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = "账号[" + p_reqQrySttm.actNum + "]商户配置信息!未配置merchantId";
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = "未找到账号[" + p_reqQrySttm.actNum + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.totalNum = String.valueOf(totalNum);
        tmpRespHeader[0] = tmpRespCode;
        tmpRespHeader[1] = tmpRespInfo;
        return tmpRespHeader;
    }

    /**
     * 网关支付对账单下载
     *
     * @param p_reqQrySttm
     * @param retAts
     * @return
     * @throws Exception
     */
    public String[] getGatewayStatementBySFTP(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
        String[] tmpRespHeader = new String[]{"", ""};
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.totalNum = "0";
        int totalNum = 0;
        FtpReceiver ftpReceiver = null;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "gateway");
            if (actItem != null) {
                // FTP服务器配置信息
                String localPath = getBankConfig().getValueAsString("statementFileFath");
                String merchantId = actItem.merchantId;
                if (merchantId != null&& !"".equals(merchantId)) {
                    if (!"".equals(localPath)) {
                        localPath = StringHelper.trimEnd(localPath, File.separator) + File.separator;
                        ftpReceiver = downActStatement(localPath);
                        if (ftpReceiver == null || ftpReceiver.isCompleted) {
                            // 从本地文件读取对账单数据
                            //文件名格式：商户号_商户交易日期_生成文件时间戳（yyyyMMddHHmmss）_x_y.zip
                            //商户号:长度 15 位
                            //商户交易日期:8 位
                            //时间戳:yyyyMMddHHmmss
                            String filePath =localPath + Format.Date8Format.format(p_reqQrySttm.getBusDate());
                            String[] files = FileHelper.listFiles(filePath);
                            WriteBankLogLn("从" + filePath + "读取对账单文件");
                            if (files != null) {
                                List<String> list = Arrays.asList(files);
                                for (String file : files) {
                                    String dirName = file.substring(0, file.lastIndexOf("."))+".txt";
                                    if (!file.startsWith(merchantId) ||(file.endsWith(".zip")&&list.contains(dirName))) {
                                        continue;
                                    }
                                    if (file.endsWith(".zip")) {
                                        WriteBankLogLn("开始解压文件" + file);
                                        ZipHelper.unzipFile(filePath + File.separator + file, filePath, true);
                                        //解压后的文件夹
                                        file = dirName;
                                    }
                                    String content = FileHelper.readFileText(filePath + File.separator + file, getCharset());
                                    if (content == null || "".equals(content)) {
                                        WriteBankLogLn(file + "文件内容有误");
                                        continue;
                                    }
                                    WriteBankLogLn("对账单文件内容:\r\n" + content);
                                    String spliter = "\n";
                                    if (content.contains("\r\n")) {
                                        spliter = "\r\n";
                                    }

                                    String[] line = content.split(spliter);
//                                    String sign = line[line.length - 1]; //签名原字段
                                    StringBuilder plain = new StringBuilder();
                                    plain.append(line[0]);
                                    tmpRespCode = "0";
                                    String[] lines = line[0].split("\\|", -1);
                                    if (lines.length >= 15) {
                                        totalNum = totalNum + Integer.parseInt(lines[1].trim());
                                    } else {
                                        WriteBankLogLn("对账单文件格式有误,请检查");
                                        continue;
                                    }
                                    for (int x = 1; x < line.length-1;x++) {
                                        plain.append(line[x]);
                                        lines = line[x].split("\\|", -1);
                                        if (lines.length >= 30) {
                                            String orderState = lines[10].trim();
                                            RetAtsStatementDetail retDetail = new RetAtsStatementDetail();
                                            retDetail.busTime = lines[0].trim()+lines[17].trim();
                                            retDetail.busType = lines[8].trim();
                                            retDetail.bkSeq = lines[5].trim();
                                            retDetail.askNumber = lines[5].trim();
                                            retDetail.cur = convertCurToATS(lines[7].trim());
                                             //0401退票
                                            if ("0401".equals(retDetail.busType)) {
                                                retDetail.refundAmt = StringHelper.amountDivide100(lines[14].trim());
                                                //1027退款调账成功  0000成功
                                                if ("1027".equals(orderState)) {
                                                    retDetail.refundState = RefundState.RefundSuccess;
                                                } else {
                                                    retDetail.refundState = RefundState.RefundFail;
                                                }
                                            } else {
                                                retDetail.amount = StringHelper.amountDivide100(lines[14].trim());
                                                if ("0000".equals(orderState)) {
                                                    retDetail.transState = TransState.Success;
                                                } else {
                                                    retDetail.transState = TransState.Fail;
                                                }
                                            }
                                            retAts.writeRetDetail(retDetail);
                                        }
                                    }

                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = filePath + "路径下不存在对账单文件。";
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "SFTP获取对账单失败:" + ftpReceiver.connMsg + "+" + ftpReceiver.connState;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = "未配置本地对账存放路径";
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = "账号[" + p_reqQrySttm.actNum + "]商户配置信息!未配置merchantId";
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = "未找到账号[" + p_reqQrySttm.actNum + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.totalNum = String.valueOf(totalNum);
        tmpRespHeader[0] = tmpRespCode;
        tmpRespHeader[1] = tmpRespInfo;
        return tmpRespHeader;
    }

    FtpReceiver downActStatement(String localPath) throws Exception {
        FtpReceiver ftpReceiver = null;
        FtpSet ftpSet = bankFront.getFtpSet("statement");
        SftpPortClient sftpPortClient = null;
        try {
            sftpPortClient = new SftpPortClient(ftpSet);
            String downDir = StringHelper.trimEnd(ftpSet.downDir, "/") + "/";
            WriteBankLogLn("对账单下载地址[" + ftpSet.serverIP + ":" + ftpSet.port + "/" + downDir + "]");
            String local = "";
                    ftpReceiver = sftpPortClient.listFiles(ftpSet.downDir, 0);
            if (ftpReceiver.isCompleted && !"".equals(ftpReceiver.connMsg)) {
                String[] filename = ftpReceiver.connMsg.split(",");
                for (String file : filename) {
                    WriteBankLogLn("开始下载对账单文件:"+file);
                    String[] fileStr = file.substring(file.lastIndexOf("/")+1).split("_");
                    if (fileStr.length >=5) {
                        //本地路径+yyyyMMdd+文件名
                        local = localPath + fileStr[1] + File.separator ;
                        File dir = new File(local);
                        if (!dir.exists()) {
                            dir.mkdirs();
                        }
                        ftpReceiver = sftpPortClient.downloadFile("", file, local + file);
                        if (!ftpReceiver.isCompleted) {
                            break;
                        }
                        sftpPortClient.deleteFile(ftpSet.downDir, file);

                    }
                }
            } else if (ConnState.FILE_NOT_EXISTS.equals(ftpReceiver.connState)) {
                ftpReceiver = null;
            }
        } catch (Exception e) {
            throw e;
        }

        return ftpReceiver;
    }


}
